//
//  BaseLoadingLayer.h
//  zoudasmallworld
//
//  Created by 周俊 on 14-6-13.
//
//

#ifndef __zoudasmallworld__BaseLoadingLayer__
#define __zoudasmallworld__BaseLoadingLayer__

#include <thread>
#include <mutex>
#include <list>

#include "BaseLayer.h"
#include "../base/Macro.h"
#include "../base/ThreadPool.h"

TSP_NS_START

class BaseLoadingLayer : public TSP::BaseLayer
{
public:
    enum
    {
        kEventUnknown = 1000,
        kOnComplete,
        kEventMax
    };

    virtual ~BaseLoadingLayer();
    virtual bool init();
    static BaseLoadingLayer* create();

    /* 进入退出重载 */
    virtual void onEnter();
    virtual void onExit();
    virtual void update(float delta);


    template<class F, class... Args>
    std::future<typename std::result_of<F(Args...)>::type> enqueue(F&& f, Args&&... args);

    void resetProgress();

    inline unsigned int getMaxTaskNum()
    {
        return m_threadPool->getMaxTaskNum();
    }
    inline unsigned int getCurrentFinishedNum()
    {
        return m_threadPool->getCurrentFinishedNum();
    }
    inline unsigned int getNotCompletedTaskNum()
    {
        return m_threadPool->getNotCompletedTaskNum();
    }
    inline unsigned int getProgressPercentage()
    {
        return m_threadPool->getProgressPercentage();
    }

protected:
    BaseLoadingLayer();
    virtual void completeLoading();

    ThreadPool* m_threadPool;

private:
    TSP_DISALLOW_COPY_AND_ASSIGN(BaseLoadingLayer);
};

template<class F, class... Args>
std::future<typename std::result_of<F(Args...)>::type> BaseLoadingLayer::enqueue(F&& f, Args&&... args)
{
    scheduleUpdate();
    return m_threadPool->enqueue(f, args...);
}

TSP_NS_END
#endif /* defined(__zoudasmallworld__BaseLoadingLayer__) */
